﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Vertica.Data.VerticaClient;

namespace Hp.Vertica.Client.Internal
{
    public abstract class VerticaDataType
    {
        public abstract String Name { get; }
        public virtual Int32 Size { get; set; }
        public virtual Int32 Precision { get; set; }
        public virtual Int32 Scale { get; set; }

        public override string ToString()
        {
            return this.Name;
        }
        public abstract VerticaType VerticaType { get; }

        private static Dictionary<String, Type> verticaTypeTable = new Dictionary<string, Type>();

        private static Dictionary<String, String> verticaAliasTable = new Dictionary<string, string>();

        public static VerticaDataType CreateVerticaDataType(String tName, Int32 maxLength, Int32 precision, Int32 scale)
        {
            tName = verticaAliasTable.ContainsKey(tName.ToUpper()) ? verticaAliasTable[tName.ToUpper()] : tName.ToUpper();
            if (!verticaTypeTable.ContainsKey(tName))
            {
                foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
                {
                    if (("VerticaDataType_" + tName.Replace(" ", "")).ToUpper() == t.Name.ToUpper())
                    {
                        verticaTypeTable.Add(tName, t);
                        break;
                    }
                }
            }
            Type type = verticaTypeTable[tName];
            Type[] parameters = { };
            var construct = type.GetConstructor(parameters);
            Object[] arguments = { };
            object obj = construct.Invoke(arguments);
            VerticaDataType result = obj as VerticaDataType;
            result.Size = maxLength;
            result.Precision = precision;
            result.Scale = scale;
            return result;
        }
    }
}
